﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Invoicing.Model.Orders;
using Invoicing.Model.Members;
using Invoicing.Model.Financial;
using Utils;
namespace Invoicing.Command.Orders
{
    public class PaidOrderCommand
    {
        public static PaidOrderModel NewOrder(PaidOrderModel order)
        {
            if (order != null)
            {
                using (DBCentre db = new DBCentre())
                {
                    var orderMethod = (OrderMethod)Enum.Parse(typeof(OrderMethod), order.Method.ToString());
                    order.OrderNo = Comm.Orders.CreateOrderNo(db, orderMethod);
                    var dOrder = Convertor.ConvertFrom<PaidOrder, PaidOrderModel>(order);
                    var dItems = Convertor.ConvertFromCollection<PaidOrderDetail, PaidOrderDetailModel>(order.Items);
                    foreach (var it in dItems)
                        dOrder.PaidOrderDetails.Add(it);
                    db.DataContext.PaidOrders.Add(dOrder);

                    var lastPaid = db.DataContext.PaidOrders.Where(p => p.CustomerID == order.CustomerID).OrderByDescending(p => p.ID).FirstOrDefault();
                    decimal balance = 0;
                    if (lastPaid != null)
                        balance = lastPaid.Balance;
                    if (balance > 0)
                    {
                        dOrder.PaidOrderDetails.Add(new PaidOrderDetail()
                        { 
                             Money=balance,
                             BankID=7
                        });
                        dOrder.TotalMoney += balance;
                    }
                    
                    var dealOrderNos = order.DealOrderList.Split(',');
                    var deals = db.DataContext.DealOrders.Where(p => dealOrderNos.Contains(p.OrderNo) && (new int[] { 5, 8 }).Contains(p.OrderStatus)).OrderBy(p => p.ID).ToList();
                    if (deals.Count==0)
                        throw new InvoicingException("没有需要支付的交易单据。");
                    var c = 0;
                    var sum = order.TotalMoney + balance;
                    dOrder.DealOrderList = "";
                    
                    foreach (var d in deals)
                    {
                        if (sum >= d.TotalMoney)
                        {
                            d.PaidMoney = d.TotalMoney;
                            sum -= d.TotalMoney;
                            c++;
                            d.OrderStatus = (int)OrderStatus.Paid;
                            dOrder.DealOrderList += "," + d.OrderNo;
                        }
                        else
                            break;
                    }
                    //if (c == 0)
                    //    throw new InvoicingException("金额不够支付一个交易单据。");
                    if (dOrder.DealOrderList.Length > 0)
                        dOrder.DealOrderList = dOrder.DealOrderList.Substring(1);
                    dOrder.Balance = sum;

                    db.DataContext.SaveChanges();
                    order.ID = dOrder.ID;
                    return order;
                }
            }
            return null;
        }
        /// <summary>
        /// 查询单据列表
        /// </summary>
        /// <param name="sea"></param>
        /// <returns></returns>
        public static PaidOrderCollection GetOrders(PaidOrderQuery sea)
        {
            var result = new PaidOrderCollection();
            using (DBCentre db = new DBCentre())
            {
                IQueryable<PaidOrder> q = db.DataContext.PaidOrders;
                if (sea != null)
                {
                    if (!string.IsNullOrEmpty(sea.OrderNo))
                        q = q.Where(p => p.OrderNo == sea.OrderNo);
                    if (sea.CustomerID > 0)
                        q = q.Where(p => p.CustomerID == sea.CustomerID);
                    if (sea.OperatorUserID > 0)
                        q = q.Where(p => p.OperatorUserID == sea.OperatorUserID);
                    if (sea.OrderDateBefore != null)
                        q = q.Where(p => p.NoteDate.CompareTo(sea.OrderDateBefore.Value) >= 0);
                    if (sea.OrderDateAfter != null)
                        q = q.Where(p => p.NoteDate.CompareTo(sea.OrderDateAfter.Value) <= 0);
                    if (sea.Method > 0)
                        q = q.Where(p => p.Method == sea.Method);
                }
                var n = q.Count();
                if (n > 0)
                {
                    q = q.OrderByDescending(p => p.ID);
                    if (sea != null && sea.PageSize > 0)
                        q = q.Skip(sea.PageSize * sea.PageIndex).Take(sea.PageSize);
                    var lst = q.ToList();
                    result = Convertor.ConvertCollection<PaidOrderModel, PaidOrder, PaidOrderCollection>(lst);
                    result.TotalRecordsCount = n;
                    if (sea != null)
                    {
                        foreach (var m in result)
                        {
                            var d = lst.Find(p => p.OrderNo == m.OrderNo);
                            if (sea.GetCustomer)
                                m.Customer = Convertor.ConvertTo<CustomerModel, Customer>(d.Customer);
                            if (sea.GetItems)
                                m.Items = Convertor.ConvertCollection<PaidOrderDetailModel, PaidOrderDetail, PaidOrderDetailCollection>(d.PaidOrderDetails);
                            if (sea.GetOperator)
                                m.Operator = d.User.RealName;
                        }
                    }
                }
            }
            return result;
        }

        public static PaidOrderModel GetOrder(string orderNo)
        {
            if (!string.IsNullOrEmpty(orderNo))
            {
                using (DBCentre db = new DBCentre())
                {
                    var d = db.DataContext.PaidOrders.FirstOrDefault(p => p.OrderNo == orderNo);
                    if (d != null)
                    {
                        var m = Convertor.ConvertTo<PaidOrderModel, PaidOrder>(d);
                        m.Customer = Convertor.ConvertTo<CustomerModel, Customer>(d.Customer);
                        m.Items = Convertor.ConvertCollection<PaidOrderDetailModel, PaidOrderDetail, PaidOrderDetailCollection>(d.PaidOrderDetails);
                        foreach (var o in m.Items)
                        {
                            var di = d.PaidOrderDetails.FirstOrDefault(p => p.ID == o.ID);
                            o.Bank = Convertor.ConvertTo<BankModel, Bank>(di.Bank);
                        }
                        return m;
                    }
                }
            }
            return null;
        }
    }
}
